<template>
	<div style="display: flex">
		<el-upload
			ref="upload"
			:class="{ hide_box: upload_btn }"
			v-model:file-list="fileList"
			:action="picUrl + '/common/upload'"
			list-type="picture-card"
			:limit="props.limit"
			:multiple="props.limit > 1"
			:on-change="handleChange"
			:before-upload="beforeAvatarUpload"
			:on-success="handleAvatarSuccess"
			:on-preview="handlePictureCardPreview"
			:before-remove="beforeRemove"
			:on-remove="onRemove"
		>
			<el-icon>
				<Plus />
			</el-icon>
		</el-upload>

		<el-dialog v-model="dialogVisible">
			<img w-full :src="dialogImageUrl" alt="Preview Image" />
		</el-dialog>
	</div>
</template>

<script lang="ts" setup>
import { nextTick, onMounted, ref } from "vue"
import { ElMessage, genFileId } from "element-plus"
import { Plus, Close } from "@element-plus/icons-vue"
import type { UploadProps, UploadRawFile } from "element-plus"
import { getUrl } from "/@/utils/axios"

const props = defineProps({
	limit: {
		type: Number,
		default: 1
	},
	type: {
		type: String,
		default: "image"
	},
	//仅限征集项目
	fengmian: {
		type: String,
		default: ""
	}
})
const upload = ref()
const dialogImageUrl = ref("")
const dialogVisible = ref(false)
const model = defineModel<any>()
const picUrl = getUrl()
const fileList: anyObj = ref([])
const upload_btn = ref(false)
const videoCover = ref("")

const handleChange = async (file, fileLists) => {
	if (props.limit != 1) {
		if (fileLists.length == props.limit) {
			upload_btn.value = true
		}
	} else {
		upload_btn.value = true
	}
}
const handleAvatarSuccess: UploadProps["onSuccess"] = async (response, uploadFile, uploadFiles) => {
	console.log(1, response)
	console.log(2, uploadFile)
	console.log(3, uploadFiles)
	console.log(fileList.value)
	if (props.type == "video") {
		const frame = await captureFrame(uploadFile, 1) //第1秒的视频画面
		if (props.limit == 1) {
			fileList.value[0].url = frame.url
		}
	}
	if (props.limit == 1) {
		model.value = response.data
	} else {
		try {
			model.value = fileList.value.map((i) => i.response.data)
		} catch (err) {}
	}
}
const onRemove = (e, a) => {
	if (props.limit == 1) {
		model.value = ""
	} else {
		try {
			model.value = a.map((i) => i.response.data.path)
		} catch (err) {}
	}
	upload_btn.value = false
}
const beforeRemove = (e, a) => {
	// if (props.limit == 1) {
	//   model.value = "";
	// } else {
	//   try {
	//     model.value = a.map(i => i.response.data.path);
	//   } catch (err) {
	//
	//   }
	// }
	// upload_btn.value = false;
}

const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
	console.log(uploadFile.url!)
	console.log(11111111111)
	dialogImageUrl.value = uploadFile.url!
	dialogVisible.value = true
}

const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
	// console.log(123123);
	// if (rawFile.size / 1024 / 1024 > 2) {
	// 	ElMessage.error("图片大于 2MB!");
	// 	return false;
	// }
	//
	//
	// if (rawFile.type == "image/jpeg" || rawFile.type == "image/png") {
	// 	return true;
	// } else {
	// 	ElMessage.error("请上传jpg/png格式的图片!");
	// 	return false;
	// }

	// if (rawFile.type !== "image/jpeg") {
	//   ElMessage.error("Avatar picture must be JPG format!");
	//   return false;
	// } else if (rawFile.size / 1024 / 1024 > 2) {
	//   ElMessage.error("Avatar picture size can not exceed 2MB!");
	//   return false;
	// }
	return true
}

/**
 * 捕获视频帧
 * @param {File} videoFile - 要捕获的视频文件
 * @param {number} time - 视频中的时间点，默认为0
 * @return {Promise} 返回一个解析为包含blob和url的帧对象的Promise
 */
const captureFrame = (videoFile, time = 0) => {
	return new Promise((resolve) => {
		const video = document.createElement("video")
		video.currentTime = time
		video.muted = true // 静音
		video.autoplay = true // 自动播放
		// 注册事件
		video.oncanplay = async () => {
			const frame = await drawVideo(video)
			resolve(frame)
		}
		video.src = URL.createObjectURL(videoFile.raw) // 获取blob地址
	})
}

/**
 * 从视频中绘制帧
 * @param {HTMLVideoElement} video - 视频元素
 * @return {Promise} 返回一个解析为包含blob和url的帧对象的Promise
 */
const drawVideo = (video) => {
	return new Promise((resolve) => {
		const cvs = document.createElement("canvas")
		const ctx = cvs.getContext("2d")
		ctx.drawImage(video, 0, 0, cvs.width, cvs.height)
		// 转blob
		cvs.toBlob((blob) => {
			resolve({
				blob,
				url: URL.createObjectURL(blob)
			})
		})
	})
}

/**
 * 创建预览图
 * @param {Object} frame - 包含blob和url的帧对象
 */
const createPreview = (frame) => {
	/**
	 * 将Blob对象转换为Base64字符串
	 * @param {Blob} blob - 要转换的Blob对象
	 * @return {Promise} 返回一个解析为Base64字符串的Promise对象
	 */
	function blobToBase64(blob) {
		return new Promise((resolve, reject) => {
			const reader = new FileReader()
			reader.readAsDataURL(blob)
			reader.onloadend = () => {
				resolve(reader.result)
			}
			reader.onerror = (error) => {
				reject(error)
			}
		})
	}

	blobToBase64(frame.blob).then((res) => {
		console.log(res) //保存缩略图（base64）
	})
	// 创建img元素并设置src为帧的url，然后将其添加到body中
	// const img = document.createElement('img')
	// img.src = frame.url
	// document.body.appendChild(img)
}

/**
 * 将文件转换为Base64编码格式
 * @param {Object} file - 待转换的文件对象，包含原始文件信息
 * @returns {Promise} 返回一个Promise对象，该对象在文件转换成功时解析为Base64字符串，在转换失败时拒绝为错误信息
 */
const getBase64 = (file) => {
	return new Promise((resolve, reject) => {
		// 创建一个FileReader对象，用于读取文件内容
		let reader = new FileReader()
		// 初始化文件结果变量，用于存储转换后的Base64字符串
		let fileResult = ""
		// 开始读取文件，使用DataURL格式
		reader.readAsDataURL(file.raw)
		// 监听文件读取成功事件
		reader.onload = function () {
			// 当文件读取成功时，将结果存储到fileResult变量中
			fileResult = reader.result
		}
		// 监听文件读取错误事件
		reader.onerror = function (error) {
			// 当文件读取失败时，拒绝Promise并传递错误信息
			reject(error)
		}
		// 监听文件读取结束事件
		reader.onloadend = function () {
			// 当文件读取结束时，解析Promise并返回结果
			resolve(fileResult)
		}
	})
}

onMounted(() => {
	if (!model.value) return

	if (props.limit == 1) {
		upload_btn.value = true
		if (props.fengmian) {
			fileList.value.push({ url: getUrl() + "/" + props.fengmian })
		} else {
			fileList.value.push({ url: getUrl() + "/" + model.value })
		}
	}

	if (props.limit > 1) {
		if (model.value.length == props.limit) {
			upload_btn.value = true
		}

		model.value.forEach((i) => {
			fileList.value.push({
				url: i,
				response: {
					data: getUrl() + "/" + i
				}
			})
		})
	}
})
</script>

<style scoped>
.avatar {
	width: 78px;
	height: 78px;
	display: block;
}
</style>

<style scoped lang="scss">
.avatar-uploader .el-upload {
	border: 1px dashed var(--el-border-color);
	border-radius: 6px;
	cursor: pointer;
	position: relative;
	overflow: hidden;
	transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
	border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
	font-size: 28px;
	color: #8c939d;
	width: 78px;
	height: 78px;
	text-align: center;
}

:deep(.el-upload--picture-card) {
	width: 70px;
	height: 70px;
}

:deep(.el-upload-list--picture-card) {
	height: 70px;
	display: flex;
	justify-content: center;
}

:deep(.el-upload-list__item-actions) {
	width: 70px;
	height: 70px;
}

:deep(.el-upload-list__item-thumbnail) {
	width: 70px;
	height: 70px;
}

:deep(.el-upload-list__item) {
	width: 70px;
	height: 70px;
}
</style>

<style>
.hide_box .el-upload--picture-card {
	display: none;
}
</style>
